package cn.ym.org.service.impl;

import cn.ym.basic.service.impl.BaseServiceImpl;
import cn.ym.basic.utils.AssertUtil;
import cn.ym.basic.utils.PageList;
import cn.ym.org.domain.Department;
import cn.ym.org.domain.Employee;
import cn.ym.org.mapper.DepartmentMapper;
import cn.ym.org.query.DepartmentQuery;
import cn.ym.org.service.DepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 业务层：部门
 */
@Service
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements DepartmentService {

    @Autowired
    private DepartmentMapper departmentMapper;

    /**
     * 添加
     * @param department
     */
    @Transactional//默认只读为false，默认传播机制为REQUIRED[有且仅有一个事务]
    @Override
    @CacheEvict(cacheNames = "deptTree",key = "'ALL'")
    public void add(Department department) {
        AssertUtil.isNotEmpty(department.getSn(),"亲：部门编号不能为空");
        AssertUtil.isNotEmpty(department.getName(),"亲：部门名称不能为空");
        AssertUtil.isNotEmpty(department.getDirPath(),"亲：部门层级不能为空");
        departmentMapper.add(department);
        //第一种：先删除reids里面的缓存，
        //redisTemplate.delete("deptTree");
    }

    /**
     * 修改
     * @param department
     */
    @Transactional//默认只读为false，默认传播机制为REQUIRED[有且仅有一个事务]
    @Override
    @CacheEvict(cacheNames = "deptTree",key = "'ALL'")
    public void update(Department department) {
        AssertUtil.isNotEmpty(department.getSn(),"亲：部门编号不能为空");
        AssertUtil.isNotEmpty(department.getName(),"亲：部门名称不能为空");
        AssertUtil.isNotEmpty(department.getDirPath(),"亲：部门层级不能为空");
        departmentMapper.update(department);
        //第一种：先删除reids里面的缓存，
        //redisTemplate.delete("deptTree");
    }

    /**
     * 删除
     * @param id
     */
    @Transactional//默认只读为false，默认传播机制为REQUIRED[有且仅有一个事务]
    @Override
    @CacheEvict(cacheNames = "deptTree",key = "'ALL'")
    public void delete(Long id) {
        departmentMapper.delete(id);
        //第一种：先删除reids里面的缓存，
        //redisTemplate.delete("deptTree");
    }

    /**
     * 批量删除
     * @param ids
     */
    @Transactional//默认只读为false，默认传播机制为REQUIRED[有且仅有一个事务]
    @Override
    @CacheEvict(cacheNames = "deptTree",key = "'ALL'")
    public void patchDel(Long[] ids) {
        departmentMapper.patchDel(ids);
        //第一种：先删除reids里面的缓存，
        //redisTemplate.delete("deptTree");
    }


    /**
     * 部门树
     * @return
     */
    @Override
    @Cacheable(cacheNames = "deptTree",key = "'ALL'")
    public List<Department> deptTree() {
        /**
         * 方式二
         */
        return getDeptTree();
        /**
         * 方式一：基于配置RedisConfig实现的
         */
//        if (redisTemplate.opsForValue().get("deptTree")!=null){
//            return (List<Department>) redisTemplate.opsForValue().get("deptTree");
//        }
//        List<Department> deptTree = getDeptTree();
//        redisTemplate.opsForValue().set("deptTree",deptTree,7, TimeUnit.DAYS);
//        return deptTree;
    }


    private List<Department> getDeptTree() {
        //1.先查询出所有的部门
        List<Department> departmentList = departmentMapper.findAll();
        //2.通过循环装到map集合里面---方便通过id查询部门对象
        HashMap<Long, Department> map = new HashMap<>();
        for (Department department : departmentList) {
            map.put(department.getId(),department);
        }
        //3.再用一个集合来装所有的数据
        List<Department> deptTree = new ArrayList<>();
        //4.再次进行遍历部门对象
        for (Department department : departmentList) {
            if (department.getParentId()==null){//ParentId为null，代表着它就是顶级部门
                deptTree.add(department) ; //添加到部门树
            }else {//有父级部门id
                Long parentId = department.getParentId();
                //获取父部门对象
                Department parentDepartment = map.get(parentId);
               if (parentDepartment != null){//避免修改数据时 出现空指针异常
                   //将自己状态父部门的children集合中
                   parentDepartment.getChildren().add(department);
               }
            }
        }
        return deptTree;
    }



}
